// $ANTLR : "FSTParser.g" -> "FSTParser.java"$

package com.hermeneute.fsa.parser;

import antlr.TokenBuffer;
import antlr.TokenStreamException;
import antlr.TokenStreamIOException;
import antlr.ANTLRException;
import antlr.LLkParser;
import antlr.Token;
import antlr.TokenStream;
import antlr.RecognitionException;
import antlr.NoViableAltException;
import antlr.MismatchedTokenException;
import antlr.SemanticException;
import antlr.ParserSharedInputState;
import antlr.collections.impl.BitSet;

import com.hermeneute.fsa.*;
import com.hermeneute.fsa.editors.FSTReader;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.resources.IResource;

import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;

import java.util.*;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.StringReader;
import java.util.Hashtable;
import antlr.CharScanner;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IFile;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.File;

public class FSTParser extends antlr.LLkParser       implements FSTParserTokenTypes
 {

	IProject project;
	IPath path;
	IProgressMonitor monitor;
	FSTOperator op = new FSTOperator();
	Hashtable amem = new Hashtable();
	Hashtable camem = new Hashtable();
	FSTResult res;
	int line = 0;
	public void setPM(IProgressMonitor m){
		monitor = m;
	}
	public void setProject(IProject p){
		project = p;
	}
	public void setPath(IPath p){
		path = p;
	}

protected FSTParser(TokenBuffer tokenBuf, int k) {
  super(tokenBuf,k);
  tokenNames = _tokenNames;
}

public FSTParser(TokenBuffer tokenBuf) {
  this(tokenBuf,6);
}

protected FSTParser(TokenStream lexer, int k) {
  super(lexer,k);
  tokenNames = _tokenNames;
}

public FSTParser(TokenStream lexer) {
  this(lexer,6);
}

public FSTParser(ParserSharedInputState state) {
  super(state,6);
  tokenNames = _tokenNames;
}

	public final void file() throws RecognitionException, TokenStreamException, Exception {
		
		
		statement();
		
				monitor.worked(1);
				if(monitor.isCanceled())throw new OperationCanceledException();
				
		{
		_loop2731:
		do {
			if ((_tokenSet_0.member(LA(1)))) {
				statement();
				
						monitor.worked(1);
						if(monitor.isCanceled())throw new OperationCanceledException();
						
			}
			else {
				break _loop2731;
			}
			
		} while (true);
		}
	}
	
	public final void statement() throws RecognitionException, TokenStreamException, Exception {
		
		Token  y1 = null;
		Token  y2 = null;
		Token  y3 = null;
		Token  y4 = null;
		Token  y5 = null;
		Token  s = null;
		Token  a1 = null;
		Token  s1 = null;
		Token  a2 = null;
		Token  y6 = null;
		Token  a3 = null;
		Token  y7 = null;
		FSTAutomaton x;
		
		switch ( LA(1)) {
		case SYMBOL:
		{
			y1 = LT(1);
			match(SYMBOL);
			match(EQ);
			{
			switch ( LA(1)) {
			case SYMBOL:
			case STRING:
			case LPAR:
			case NOT:
			case ANY:
			case ZERO:
			{
				x=expression();
				
							//System.out.println("Adding "+y1.getText());
							amem.put(y1.getText(),x);
						
				break;
			}
			case READ:
			{
				match(READ);
				y2 = LT(1);
				match(STRING);
				
							String sfin = (String)y2.getText();
							//System.out.println(project.findMember(sfout).getFullPath().toOSString());
							IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
							System.out.println(path);
							System.out.println(path.append(sfin));
							IResource ifin = root.getFile(path.append(sfin));
							File fin = ifin.getLocation().toFile();
						
					x=new FSTAutomaton(); 
					x.read(ifin.getLocation().toString());
					amem.put(y1.getText(),x);
				
				break;
			}
			default:
			{
				throw new NoViableAltException(LT(1), getFilename());
			}
			}
			}
			match(SC);
			break;
		}
		case WRITE:
		{
			match(WRITE);
			x=expression();
			match(TO);
			y3 = LT(1);
			match(STRING);
				
						String sfout = (String)y3.getText();
						//System.out.println(project.findMember(sfout).getFullPath().toOSString());
						IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
						System.out.println(path);
						System.out.println(path.append(sfout));
						IResource ifout = root.getFile(path.append(sfout));
						File fout = ifout.getLocation().toFile();
						BufferedWriter out = new BufferedWriter(new FileWriter(fout));
						try{x.write(out);ifout.refreshLocal(IResource.DEPTH_ONE, null);}
						catch(Exception fstx){throw new RecognitionException (fstx.getMessage()+", "+y3.getText());
						
				    		
					}
				
			match(SC);
			break;
		}
		case PRINT:
		{
			match(PRINT);
			x=expression();
			
						try{x.print();}
						catch(Exception fstx){throw new RecognitionException (fstx.getMessage()+", print");}
					
			match(SC);
			break;
		}
		case DISPLAY:
		{
			match(DISPLAY);
			y4 = LT(1);
			match(STRING);
			System.out.println(y4.getText());
			match(SC);
			break;
		}
		case INSERT:
		{
			match(INSERT);
			y5 = LT(1);
			match(STRING);
			match(INTO);
			x=expression();
			x.trieInsertStr((String)y5.getText());
			match(SC);
			break;
		}
		case OPTIMIZE:
		{
			match(OPTIMIZE);
			s = LT(1);
			match(SYMBOL);
			
					x=(FSTAutomaton)amem.get(s.getText());
					x=op.optimize(x);
					amem.put(s.getText(),x);
				
			match(SC);
			break;
		}
		case AUTOMATON:
		{
			a1 = LT(1);
			match(AUTOMATON);
			match(EQ);
			match(COMPILE);
			s1 = LT(1);
			match(SYMBOL);
			
					FSTSequentialTransducer st = new FSTSequentialTransducer((FSTAutomaton)amem.get(s1.getText()));
					camem.put(a1.getText(),st);
				
			match(SC);
			break;
		}
		case SL_COMMENTS:
		{
			match(SL_COMMENTS);
			match(WS);
			break;
		}
		default:
			if ((LA(1)==PARSE) && (LA(2)==AUTOMATON) && (LA(3)==FILE)) {
				match(PARSE);
				a2 = LT(1);
				match(AUTOMATON);
				match(FILE);
				y6 = LT(1);
				match(STRING);
				
						try {
							
							FSTSequentialTransducer st = (FSTSequentialTransducer)camem.get(a2.getText());
							if (st != null) {
								FSTReader fr = new FSTReader(st,new FileReader(y6.getText()));
								BufferedReader br = new BufferedReader(fr);
								
							    try { 
									String input; 
									while ((input = br.readLine()) != null) { 
									    System.out.println(input); 
									    System.out.flush(); 
									} 
									br.close();
								} catch (Exception e) { 
									System.err.println("Tagger run: " + e); 
							    } 
							} else {
								System.out.println("No Automaton found");    		
							}
							System.out.println();
						} catch (FileNotFoundException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					
				match(SC);
			}
			else if ((LA(1)==PARSE) && (LA(2)==AUTOMATON) && (LA(3)==STRING)) {
				match(PARSE);
				a3 = LT(1);
				match(AUTOMATON);
				y7 = LT(1);
				match(STRING);
				
						try {
							FSTSequentialTransducer st = (FSTSequentialTransducer)camem.get(a3.getText());
							if (st != null) {
								FSTReader fr = new FSTReader(st,new StringReader(y7.getText()));
								BufferedReader br = new BufferedReader(fr);
								
							    try { 
									String input; 
									while ((input = br.readLine()) != null) { 
									    System.out.println(input); 
									    System.out.flush(); 
									} 
									br.close(); 
								} catch (Exception e) { 
									System.err.println("Tagger run: " + e); 
							    } 
							} else {
								System.out.println("No Automaton found");    		
							}
							System.out.println();
						} catch (Exception e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					
				match(SC);
			}
		else {
			throw new NoViableAltException(LT(1), getFilename());
		}
		}
	}
	
	public final FSTAutomaton  expression() throws RecognitionException, TokenStreamException, Exception {
		FSTAutomaton a = null;
		
		
		a=intersectionExpression();
		return a;
	}
	
	public final FSTAutomaton  intersectionExpression() throws RecognitionException, TokenStreamException, Exception {
		FSTAutomaton a = null;
		
		FSTAutomaton x;
		
		a=unionExpression();
		{
		_loop2737:
		do {
			if ((LA(1)==AND)) {
				match(AND);
				x=unionExpression();
				a=op.computeIntersection(a,x);
			}
			else {
				break _loop2737;
			}
			
		} while (true);
		}
		return a;
	}
	
	public final FSTAutomaton  unionExpression() throws RecognitionException, TokenStreamException, Exception {
		FSTAutomaton a = null;
		
		FSTAutomaton x;
		
		a=productExpression();
		{
		_loop2740:
		do {
			if ((LA(1)==UNION)) {
				match(UNION);
				x=productExpression();
				a=op.computeUnion(a,x);
			}
			else {
				break _loop2740;
			}
			
		} while (true);
		}
		return a;
	}
	
	public final FSTAutomaton  productExpression() throws RecognitionException, TokenStreamException, Exception {
		FSTAutomaton a = null;
		
		FSTAutomaton x;
		
		a=subExpression();
		{
		_loop2743:
		do {
			if ((_tokenSet_1.member(LA(1)))) {
				x=subExpression();
				a=op.computeConc(new FSTAutomaton(a),x);
			}
			else {
				break _loop2743;
			}
			
		} while (true);
		}
		return a;
	}
	
	public final FSTAutomaton  subExpression() throws RecognitionException, TokenStreamException, Exception {
		FSTAutomaton a = null;
		
		
		switch ( LA(1)) {
		case SYMBOL:
		case STRING:
		case ANY:
		case ZERO:
		{
			a=atomicExpression();
			{
			switch ( LA(1)) {
			case PLUS:
			{
				match(PLUS);
				FSTAutomaton tmp =new FSTAutomaton(a); a=op.computeStar(a);a=op.computeConc(tmp,a);
				break;
			}
			case QUESTION:
			{
				match(QUESTION);
				a=op.computeQuestion(a);
				break;
			}
			case STAR:
			{
				match(STAR);
				a=op.computeStar(a);
				break;
			}
			case SYMBOL:
			case STRING:
			case SC:
			case TO:
			case AND:
			case UNION:
			case LPAR:
			case RPAR:
			case NOT:
			case ANY:
			case ZERO:
			{
				break;
			}
			default:
			{
				throw new NoViableAltException(LT(1), getFilename());
			}
			}
			}
			break;
		}
		case LPAR:
		case NOT:
		{
			a=parenthesisExpression();
			{
			switch ( LA(1)) {
			case PLUS:
			{
				match(PLUS);
				FSTAutomaton tmp =new FSTAutomaton(a); a=op.computeStar(a);a=op.computeConc(tmp,a);
				break;
			}
			case QUESTION:
			{
				match(QUESTION);
				a=op.computeQuestion(a);
				break;
			}
			case STAR:
			{
				match(STAR);
				a=op.computeStar(a);
				break;
			}
			case SYMBOL:
			case STRING:
			case SC:
			case TO:
			case AND:
			case UNION:
			case LPAR:
			case RPAR:
			case NOT:
			case ANY:
			case ZERO:
			{
				break;
			}
			default:
			{
				throw new NoViableAltException(LT(1), getFilename());
			}
			}
			}
			break;
		}
		default:
		{
			throw new NoViableAltException(LT(1), getFilename());
		}
		}
		return a;
	}
	
	public final FSTAutomaton  atomicExpression() throws RecognitionException, TokenStreamException, Exception {
		FSTAutomaton a = null;
		
		
		switch ( LA(1)) {
		case ANY:
		case ZERO:
		{
			a=atomicExpressionU();
			break;
		}
		case STRING:
		{
			a=atomicExpressionP();
			break;
		}
		case SYMBOL:
		{
			a=var();
			break;
		}
		default:
		{
			throw new NoViableAltException(LT(1), getFilename());
		}
		}
		return a;
	}
	
	public final FSTAutomaton  parenthesisExpression() throws RecognitionException, TokenStreamException, Exception {
		FSTAutomaton a = null;
		
		
		switch ( LA(1)) {
		case LPAR:
		{
			match(LPAR);
			a=expression();
			match(RPAR);
			break;
		}
		case NOT:
		{
			match(NOT);
			match(LPAR);
			a=expression();
			a=op.computeNot(a);
			match(RPAR);
			break;
		}
		default:
		{
			throw new NoViableAltException(LT(1), getFilename());
		}
		}
		return a;
	}
	
	public final FSTAutomaton  atomicExpressionU() throws RecognitionException, TokenStreamException, Exception {
		FSTAutomaton a = null;
		
		String x;
		
		switch ( LA(1)) {
		case ANY:
		{
			match(ANY);
			a = new FSTAutomaton();a.anyAny();
			break;
		}
		case ZERO:
		{
			match(ZERO);
			match(COL);
			x=string();
			a = new FSTAutomaton();a.epsilonStr(x);
			break;
		}
		default:
		{
			throw new NoViableAltException(LT(1), getFilename());
		}
		}
		return a;
	}
	
	public final FSTAutomaton  atomicExpressionP() throws RecognitionException, TokenStreamException, Exception {
		FSTAutomaton a = null;
		
		String x;String y;
		
		x=string();
		a = new FSTAutomaton();a.strId(x);
		{
		switch ( LA(1)) {
		case COL:
		{
			match(COL);
			match(ZERO);
			a = new FSTAutomaton();a.epsilonStr(x);
			break;
		}
		case SYMBOL:
		case STRING:
		case SC:
		case TO:
		case AND:
		case UNION:
		case PLUS:
		case QUESTION:
		case STAR:
		case LPAR:
		case RPAR:
		case NOT:
		case ANY:
		case ZERO:
		{
			break;
		}
		default:
		{
			throw new NoViableAltException(LT(1), getFilename());
		}
		}
		}
		return a;
	}
	
	public final FSTAutomaton  var() throws RecognitionException, TokenStreamException, Exception {
		FSTAutomaton a = null;
		
		Token  x = null;
		
		x = LT(1);
		match(SYMBOL);
		a=(FSTAutomaton)amem.get((String)x.getText());if (a == null){ a = new FSTAutomaton();amem.put((String)x.getText(),a);}
		return a;
	}
	
	public final String  setExp() throws RecognitionException, TokenStreamException, Exception {
		String a = null;
		
		Token  x = null;
		
		match(LSET);
		x = LT(1);
		match(STRING);
		a=x.getText();
		match(RSET);
		return a;
	}
	
	public final String  string() throws RecognitionException, TokenStreamException, Exception {
		String a = null;
		
		Token  x = null;
		
		x = LT(1);
		match(STRING);
		a=x.getText();
		return a;
	}
	
	
	public static final String[] _tokenNames = {
		"<0>",
		"EOF",
		"<2>",
		"NULL_TREE_LOOKAHEAD",
		"SYMBOL",
		"EQ",
		"READ",
		"STRING",
		"SC",
		"WRITE",
		"TO",
		"PRINT",
		"DISPLAY",
		"INSERT",
		"INTO",
		"OPTIMIZE",
		"AUTOMATON",
		"COMPILE",
		"PARSE",
		"FILE",
		"SL_COMMENTS",
		"WS",
		"AND",
		"UNION",
		"PLUS",
		"QUESTION",
		"STAR",
		"LPAR",
		"RPAR",
		"NOT",
		"LSET",
		"RSET",
		"ANY",
		"ZERO",
		"COL",
		"LT",
		"GT",
		"PERC",
		"SL_COMMENT",
		"ESCAPE"
	};
	
	private static final long[] mk_tokenSet_0() {
		long[] data = { 1423888L, 0L};
		return data;
	}
	public static final BitSet _tokenSet_0 = new BitSet(mk_tokenSet_0());
	private static final long[] mk_tokenSet_1() {
		long[] data = { 13555990672L, 0L};
		return data;
	}
	public static final BitSet _tokenSet_1 = new BitSet(mk_tokenSet_1());
	
	}
